package j_util.database;

import j_util.database.enums.TransactionIsolationEnum;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class DatabaseLibrary {
    //Map<String url, Connection corresponding connection>
    public static Map<String, DBConnection> connectionMap = new HashMap<String, DBConnection>();

    /**
     * This class creates a new connection with the parameters set. Returns the created connection or null
     * if its creation failed;
     *
     * @param connectionURL - connections url;
     * @param user          - user name;
     * @param password;
     * @return Connection - database connection;
     */
    public static DBConnection createConnection(String connectionURL, String user, String password) {
        Connection connection;
        try {
            if (!connectionMap.containsKey(connectionURL)) {
                connection = DriverManager.getConnection(connectionURL, user, password);
                connectionMap.put(connectionURL, new DBConnection(connection));
            }
        } catch (SQLException e) {
            String driverURL = driverURLSeeker(connectionURL);
            if (driverURL == null) {
                //request driver connectionURL
            } else {
                DatabaseLibrary.loadDriver(driverURL);
            }
            try {
                connection = DriverManager.getConnection(connectionURL, user, password);
                connectionMap.put(connectionURL, new DBConnection(connection));
            } catch (SQLException e1) {
                System.out.println("DatabaseLibraries_createConnection: No suitable driver found for " + connectionURL);
                e1.printStackTrace();
            }
        }
        return connectionMap.get(connectionURL);
    }

    public static void loadDriver(String url) {
//        ClassLoader.getSystemResource(url);       //todo learn how to upload jars on memory
//        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
//            classLoader.loadClass("org.hsqldb.jdbcDriver");
        try {
            Class.forName("org.hsqldb.jdbcDriver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static boolean setTransactionReadingWay(TransactionIsolationEnum transactionReadingWay, String url) throws SQLException {
        if (!connectionMap.containsKey(url)) {
            return false;
        }
        switch (transactionReadingWay) {
            case NONE:
                connectionMap.get(url).getConnection().setTransactionIsolation(Connection.TRANSACTION_NONE);
                break;
            case READ_COMMITED:
                connectionMap.get(url).getConnection().setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
                break;
            case READ_UNCOMMITED:
                connectionMap.get(url).getConnection().setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
                break;
            case REPEATABLE_READ:
                connectionMap.get(url).getConnection().setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
                break;
            case SERIALIZABLE:
                connectionMap.get(url).getConnection().setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
                break;
        }
        return true;
    }

    public static void setAutocommitSettings(String url) throws SQLException {
        boolean autocommit = false;
        try {
            autocommit = connectionMap.get(url).getConnection().getAutoCommit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (autocommit) {
            connectionMap.get(url).getConnection().setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
        } else {
            connectionMap.get(url).getConnection().setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
        }
    }

//    public void getMetadata(){
//        Iterator results = connectionMap.get("").getMetaData();
//    }

    private static String driverURLSeeker(String connectionURL) {
        String[] array = connectionURL.split(":");
        array[1] = array[1].toUpperCase();
        if (array[1].equals("HSQLDB")) {
            return "../src/j_util/database/lib/hsqldb.jar";
        } //continue with else-if
        return null;
    }
}
